﻿#include <iostream>

#include "Command.h"
#include "CommandInvoker.h"
#include "CommandReceiver.h"

#include "CommandManage.h"

using namespace std;

void CommandManage::Command(int argc, char *argv[])
{
    vector<CmdParameter> commands;
    
    // 命令行解析
    // 从1开始，跳过程序名
    for (int i = 1; i < argc; ++i) 
    {        
        CmdParameter cmdParm;

        const string& command = argv[i];
        cmdParm.m_name = command;

        if (command == "trapezoid") 
        {
            string name, width, height, theta;
            for (++i; i < argc && argv[i][0] == '-'; ++i) 
            {
                if (string(argv[i]).find("-name=") == 0)  name = argv[i] + 6;
                else if (string(argv[i]).find("-width=") == 0) width = argv[i] + 7;
                else if (string(argv[i]).find("-height=") == 0) height = argv[i] + 8;
                else if (string(argv[i]).find("-theta=") == 0) theta = argv[i] + 7;
                else;
            }
            --i; // 回退一步，避免跳过下一个命令

            cmdParm.m_parameters.push_back({ "-name", name });
            cmdParm.m_parameters.push_back({ "-width", width });
            cmdParm.m_parameters.push_back({ "-height", height });
            cmdParm.m_parameters.push_back({ "-theta", theta });
            commands.push_back(cmdParm);
        }
        else if (command == "extrude")
        {
            string name, source, distance;
            for (++i; i < argc && argv[i][0] == '-'; ++i)
            {
                if (string(argv[i]).find("-name=") == 0)  name = argv[i] + 6;
                else if (string(argv[i]).find("-source=") == 0)  source = argv[i] + 8;
                else if (string(argv[i]).find("-distance=") == 0) distance = argv[i] + 10;
            }
            --i; // 回退一步，避免跳过下一个命令
            
            cmdParm.m_parameters.push_back({ "-name", name });
            cmdParm.m_parameters.push_back({ "-source", source });
            cmdParm.m_parameters.push_back({ "-distance", distance });
            commands.push_back(cmdParm);
        }  
        else if (command == "show") 
        {
            // 命令入队
            commands.push_back(cmdParm);
        }
        else if(command == "clear")
        {           
            // 命令入队
            commands.push_back(cmdParm);
        }
        else 
        {
            cout << "unknown_cmd: " << command << endl;
        }
    }
     Command(commands);
}

bool CommandManage::Command(const std::string &command)
{    
    // 命令行解析
    vector<string> args = CommandManage::split(command);
    for(auto x : args) cout << x << endl; 
    if(args.empty()) return false;

    CmdParameter cur_cmd;
    cur_cmd.m_name = args[0];    
    for (int i = 1; i < args.size(); ++i)
    {
        cout << parseKeyValue(args[i]).first << " " << parseKeyValue(args[i]).second << endl;
        cur_cmd.m_parameters.push_back(parseKeyValue(args[i]));
    }
        
    vector<CmdParameter> commands;
    commands.push_back(cur_cmd);
    return Command(commands);
}

bool CommandManage::Command(const vector<CmdParameter>& commands)
{
    if(commands.empty()) return false;
    CommandInvoker invoker;     // 命令行调用者，维护cmd队列
    CommandReceiver receiver;   // 命令行接收者，维护具体的实现接口

    for(auto& cmd : commands)
    {        
        if (cmd.m_name == "trapezoid")
        {            
            string name, width, height, theta;
            for (auto& p : cmd.m_parameters)
            {
                if (p.first == "name")  name = p.second;
                else if (p.first == "width") width = p.second;
                else if (p.first == "height") height = p.second;
                else if (p.first == "theta") theta = p.second;
                else;
            }

            if(name.empty() || width.empty() || height.empty() || theta.empty()) continue;
            invoker.addCommand(new TrapezoidCommand(&receiver, name, width, height, theta));
        } 
        else if (cmd.m_name == "extrude")
        {
            string name, source, distance;
            for (auto& p : cmd.m_parameters)
            {
                if (p.first == "name")  name = p.second;
                else if (p.first == "source")  source = p.second;
                else if (p.first == "distance") distance = p.second;
            }
            // 命令入队
            if(name.empty() || source.empty() || distance.empty()) continue;
            invoker.addCommand(new ExtrudeCommand(&receiver, name, source, distance));
        }        
        else if (cmd.m_name == "show") 
        {
            // 命令入队
            invoker.addCommand(new ShowCommand(&receiver));
        }
        else if(cmd.m_name == "clear")
        {           
            // 命令入队
            invoker.addCommand(new ClearCommand(&receiver));
        }
        else 
        {
            cout << "unknown_cmd: " << cmd.m_name << endl;
            continue;
        }
    }

    if(invoker.isCmdListEmpty()) return false;

    invoker.executeCommands();
    return true;
}

vector<string> CommandManage::split(const string &str)
{
    vector<string> res;
    string tmp;
    bool inQuotes = false;  // 是否在引号内
    char quoteChar = '\0';  // 当前引号类型（'或"）

    for (char c : str) 
    {
        if (inQuotes) 
        {
            // 引号内的内容直接追加
            tmp += c;
            if (c == quoteChar) 
            {
                inQuotes = false;
                quoteChar = '\0';
            }
        } 
        else 
        {
            if (c == '\'' || c == '"') 
            {
                // 进入引号模式
                inQuotes = true;
                quoteChar = c;
                tmp += c;  // 保留引号（可选，根据需求调整）
            } 
            else if (isspace(c)) 
            {
                // 空格分割参数
                if (!tmp.empty()) 
                {
                    res.push_back(tmp);
                    tmp.clear();
                }
            } 
            else 
            {
                tmp += c;
            }
        }
    }

    // 处理最后一个参数
    if (!tmp.empty()) 
    {
        res.push_back(tmp);
    }

    return res;
}

pair<string, string> CommandManage::parseKeyValue(const string &arg) 
{
    size_t eqPos = arg.find('=');
    if (eqPos == string::npos || arg[0] != '-') 
    {
        return make_pair("", "");  // 无效格式
    }

    string key = arg.substr(1, eqPos - 1);  // 跳过开头的'-'
    string value = arg.substr(eqPos + 1);

    // 处理引号包裹的值（如 -name="a b"）
    if (!value.empty() && (value.front() == '"' || value.front() == '\'')) 
    {
        char quote = value.front();
        value = value.substr(1, value.size() - 2);  // 去除引号
    }

    return make_pair(key, value);
}